// 导入axios库和Vue的h函数
import axios from "axios";

// 创建一个axios实例，设置响应类型为arraybuffer
const service = axios.create({
    responseType: 'arraybuffer'
});

/**
 * 配置请求拦截器
 * 每次发送请求前，将sessionStorage中的tokenStr添加到请求头的Authorization字段中
 * 这样，后端可以验证请求的合法性
 *
 * @param {Object} config - 请求配置对象
 * @return {Object} - 返回配置对象，添加了Authorization头
 */
service.interceptors.request.use(config => {
    config.headers['Authorization'] = window.sessionStorage.getItem('tokenStr');
    return config;
}, error => {
    console.log(error)
})

// 使用服务拦截器对响应进行处理
service.interceptors.response.use(res => {
    // 获取响应头
    const headers = res.headers;
    // 定义正则表达式，用于检测内容类型是否为 application/json
    let reg = RegExp('/application\/json/')
    // 检查内容类型是否匹配 application/json
    if (headers['content-type'].match(reg)) {
        // 如果是 JSON 类型的数据，将其转换为字符串
        res.data = unitToString(res.data)
    } else {
        // 如果不是 JSON 类型的数据，准备下载文件
        let fileDownload = require('js-file-download');
        // 从内容处置头中提取文件名
        let fileName = headers['content-disposition'].split(';')[1].split('filename=')[1];
        // 获取内容类型
        let contentType = headers['content-type'];
        // 解码文件名
        fileName = decodeURIComponent(fileName);
        // 调用文件下载函数，将响应数据作为文件下载
        fileDownload(res.data, fileName, contentType);
    }
}, error => {
    // 错误处理：打印错误信息
    console.log(error)
});


/**
 * 将单位数组转换为字符串
 *
 * 此函数的目的是将一个包含单位编码的数组转换为可读的字符串形式
 * 它通过两次编码转换来确保即使是对特殊字符也能正确处理
 *
 * @param {Array} unitArray - 一个包含单位编码的数组
 * @returns {Object} - 从编码数组转换得到的JSON对象
 */
function unitToString(unitArray) {
    // 编码
    // 将单位数组转换为字符数组，然后合并为单个字符串
    let encodedString = String.fromCharCode.apply(null, new Uint8Array(unitArray))
    // 解码
    // 对字符串进行解码，以处理特殊字符并确保它们被正确呈现
    let decodedString = decodeURIComponent(escape(encodedString));
    // 解析解码后的字符串为JSON对象并返回
    return JSON.parse(decodedString)
}


// 封装请求
let base = ''
export const downloadRequest = (url, params) => {
    return service({
        method: 'get',
        url: `${base}${url}`,
        data: params
    })
}

export default service;
